home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / xvisrc.zip / PC386.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  6KB  |  284 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)pc386.c    2.1 (Chris & John Downey) 7/29/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     pc386.c
  14. * module function:
  15.     Routines for MS-DOS 386 protected mode version.
  16.  
  17.     This file implements the same routines as ibmpc_a.asm &
  18.     msdos_a.asm, which are for the real mode version.
  19.  
  20.     Zortech C++ version 3.0 or later & an appropriate DOS extender
  21.     package (such as PharLap's) are required.
  22. * history:
  23.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  24.     Originally by Tim Thompson (twitch!tjt)
  25.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  26.     Heavily modified by Chris & John Downey
  27. ***/
  28.  
  29. #include "xvi.h"
  30.  
  31. #include <cerror.h>
  32. #include <controlc.h>
  33.  
  34. /*
  35.  * Virtual mode handling.
  36.  *
  37.  * On EGA's & VGA's, the number of rows in text modes can vary because
  38.  * fonts with different sizes can be loaded, so we use virtual modes
  39.  * to contain the additional information needed. (Actually, we handle
  40.  * it a bit simplistically because the Zortech display library only
  41.  * knows about certain cases: 25 rows (default), 43 rows (EGA with
  42.  * 8 x 8 font) & 50 rows (VGA with 8 x 8 font). The last two are
  43.  * treated as equivalent.)
  44.  */
  45. #define MONO25X80    2
  46. #define COLOUR25X80    3
  47. #define MDA25X80    7
  48. #define MASK43        043000
  49. #define COLOUR43X80    (COLOUR25X80 | MASK43)
  50. #define MONO43X80    (MONO25X80 | MASK43)
  51. #define MDA43X80    (MDA25X80 | MASK43)
  52.  
  53. static unsigned
  54. getvmode()
  55. {
  56.     unsigned    mode;
  57.  
  58.     if ((mode = disp_getmode()) == COLOUR25X80 || mode == MONO25X80 ||
  59.                                 mode == MDA25X80) {
  60.     if (disp_numrows > 25) {
  61.         return mode | MASK43;
  62.     }
  63.     }
  64.     return mode;
  65. }
  66.  
  67. static void
  68. setvmode(unsigned vmode)
  69. {
  70.     {
  71.     int    mode;
  72.  
  73.     if (disp_getmode() != (mode = vmode & ~MASK43)) {
  74.         disp_close();
  75.         disp_setmode(mode);
  76.         disp_open();
  77.     }
  78.     }
  79.     {
  80.     unsigned    m43;
  81.  
  82.     m43 = vmode & MASK43;
  83.     if (disp_ega && ((m43 && disp_numrows <= 25) ||
  84.              (!m43 && disp_numrows > 25))) {
  85.         disp_close();
  86.         if (m43) {
  87.         disp_set43();
  88.         } else {
  89.         disp_reset43();
  90.         }
  91.         disp_open();
  92.     }
  93.     }
  94. }
  95.  
  96. static unsigned startmode;        /* system virtual mode */
  97.  
  98. #if 0
  99.  
  100. /*
  101.  * Critical error handler.
  102.  *
  103.  * See notes in msdos_a.asm.
  104.  */
  105. static int _far _cdecl
  106. criterr(int *pax, int *pdi)
  107. {
  108.     *pax = ((_osmajor >= 3) ? 3 : 0);
  109. }
  110.  
  111. #endif
  112.  
  113. /*
  114.  * Keyboard interrupt handler.
  115.  */
  116. static void _cdecl
  117. inthandler(void)
  118. {
  119.     kbdintr = 1;
  120. #if 0
  121.     return(-1);    /* don't chain to previously installed vector */
  122. #endif
  123. }
  124.  
  125. /*
  126.  * Install interrupt handlers.
  127.  */
  128. void
  129. msdsignal(unsigned char *flagp)
  130. {
  131.     _controlc_handler = inthandler;
  132.     controlc_open();
  133. #if 0
  134.     _cerror_handler = criterr;
  135.     cerror_open();
  136.     int_intercept(0x23, inthandler, 0);
  137.     int_intercept(0x24, criterr, 0);
  138. #endif
  139. }
  140.  
  141. void
  142. catch_signals(void)
  143. {
  144.     /*
  145.      * Set console break flag so that we can be interrupted even
  146.      * when we're not waiting for console input.
  147.      */
  148.     dos_set_ctrl_break(1);
  149. }
  150.  
  151. /*
  152.  * Pointer to copy of previous screen.
  153.  */
  154. static unsigned short *oldscreen = NULL;
  155.  
  156. void
  157. tty_open(unsigned *prows, unsigned *pcolumns)
  158. {
  159.     if (!disp_inited) {
  160.     disp_open();
  161.     }
  162.     startmode = getvmode();
  163.  
  164.     if (disp_base) {
  165.     /*
  166.      * Allocate storage for copy of previous screen
  167.      * (except bottom line).
  168.      *
  169.      * We don't do this if we're using BIOS calls
  170.      * (indicated by disp_base == 0) because the BIOS
  171.      * doesn't do it very well (it causes a lot of cursor
  172.      * flicker).
  173.      */
  174.     oldscreen = (unsigned short *)
  175.             malloc((disp_numrows - 1) * disp_numcols *
  176.                         sizeof(unsigned short));
  177.     }
  178.     *prows = disp_numrows;
  179.     *pcolumns = disp_numcols;
  180. }
  181.  
  182. static enum {
  183.     m_INITIAL = 0,
  184.     m_SYS = 1,
  185.     m_VI = 2
  186. }    curmode;
  187.  
  188. /*
  189.  * Save screen contents & set up video state for editor.
  190.  */
  191. void
  192. tty_startv(void)
  193. {
  194.     switch (curmode) {
  195.     case m_VI:
  196.     /*
  197.      * We're already in vi mode.
  198.      */
  199.     return;
  200.     case m_SYS:
  201.     /*
  202.      * This isn't the first call. Force display
  203.      * package's variables to be re-initialized.
  204.      */
  205.     disp_close();
  206.     disp_open();
  207.     }
  208.     curmode = m_VI;
  209.     if (getvmode() != startmode) {
  210.     /*
  211.      * The display mode has changed; set it back to what we
  212.      * started with.
  213.      */
  214.     setvmode(startmode);
  215.     }
  216.     if (oldscreen) {
  217.     /*
  218.      * Save screen contents (except bottom line) so they
  219.      * can be restored afterwards.
  220.      */
  221.     disp_peekbox(oldscreen, 0, 0, disp_numrows - 2, disp_numcols - 1);
  222.     }
  223.     msm_init();
  224.     /*
  225.      * Apparently, the Microsoft mouse driver sometimes
  226.      * gets the number of screen rows wrong.
  227.      */
  228.     msm_setareay(0, (disp_numrows - 1) * 8);
  229. }
  230.  
  231. /*
  232.  * Restore video state to what it was when we started.
  233.  *
  234.  * tty_endv() can be called after it's been called already with no
  235.  * intervening tty_startv(), so we have to check.
  236.  */
  237. void
  238. tty_endv(void)
  239. {
  240.     if (curmode != m_VI) {
  241.     return;
  242.     }
  243.     /*
  244.      * Restore contents of screen.
  245.      */
  246.     if (oldscreen != NULL) {
  247.     disp_pokebox(oldscreen, 0, 0, disp_numrows - 2, disp_numcols - 1);
  248.     }
  249.     disp_flush();
  250.     curmode = m_SYS;
  251.     msm_term();
  252. }
  253.  
  254. #ifndef ABS
  255. #    define ABS(n) ((n) < 0 ? -(n) : (n))
  256. #endif
  257.  
  258. void
  259. pc_scroll(unsigned start, unsigned end, int nlines)
  260. {
  261.     if (ABS(nlines) > end + 1 - start) {
  262.     nlines = 0;
  263.     }
  264.     disp_scroll(nlines, start, 0, end, disp_numcols - 1, Pn(P_colour));
  265. }
  266.  
  267. /*
  268.  * Return a character from standard input if one is immediately
  269.  * available, otherwise -1.
  270.  *
  271.  * Don't do anything special if control-C is typed. Just return it.
  272.  */
  273. int
  274. getchnw()
  275. {
  276.     union REGS r;
  277.  
  278.     r.h.ah = 6;
  279.     r.h.dl = 0xff;
  280.     intdos(&r, &r);
  281.     return (r.e.flags & 0x40) ?        /* zero flag */
  282.     -1 : (unsigned char) r.h.al;
  283. }
  284.